<?php
/**
 * 缓存类。摘自{@link http://www.thinkphp.cn thinkphp}，已对源码进行修改
 *
 * @file            Cache.class.php
 * @package         Yap\Cache
 * @copyright       Copyright (c) 2013 {@link http://www.yaphpcms.com yaphpcms} All rights reserved
 * @license         http://www.apache.org/licenses/LICENSE-2.0.html Apache License 2.0
 * @author          liu21st <liu21st@gmail.com>
 * @date            2013-01-16 17:42:23
 * @lastmodify      $Date: 2013-01-22 05:52:40 +0000 (Tue, 22 Jan 2013) $ $Author: msl-138@163.com $
 */

namespace Yap\Cache;

/**
 * 缓存类。摘自{@link http://www.thinkphp.cn thinkphp}，已对源码进行修改
 *
 * @package         Yap\Cache
 * @copyright       Copyright (c) 2013 {@link http://www.yaphpcms.com yaphpcms} All rights reserved
 * @license         http://www.apache.org/licenses/LICENSE-2.0.html Apache License 2.0
 * @author          liu21st <liu21st@gmail.com>
 * @date            2013-01-16 17:42:23
 * @lastmodify      $Date: 2013-01-22 05:52:40 +0000 (Tue, 22 Jan 2013) $ $Author: msl-138@163.com $
 */
class Cache {
    /**
     * @var bool $_connected 连接状态标识，true已连接。默认false
     */
    protected $_connected = false;
    /**
     * @var resource $_handler 操作句柄
     */
    protected $_handler;
    /**
     * @var array $_options 缓存连接配置，key => value形式。默认array()
     */
    protected $_options = array();

    /**
     * 取得缓存类实例
     *
     * @author          liu21st <liu21st@gmail.com>
     * @lastmodify      2013-01-16 13:25:46 by mashanling
     * @return object 缓存类实例
     */
    static public function getInstance() {
        return get_instance_of(__CLASS__, 'connect', func_get_args());
    }

    /**
     * 队列缓存
     *
     * @author          liu21st <liu21st@gmail.com>
     * @lastmodify      2013-01-16 13:25:40 by mashanling
     *
     * @param string $key 缓存key
     *
     * @return mixed 缓存对应方法返回结果
     */
    protected function _queue($key) {
        static $_handler = array(
            'file'   => array('F', 'F'),
            'xcache' => array('xcache_get', 'xcache_set'),
            'apc'    => array('apc_fetch', 'apc_store'),
        );

        $queue = isset($this->_options['queue']) ? $this->_options['queue'] : 'file';
        $fun   = $_handler[$queue];
        $value = $fun[0]('think_queue');
        $value = $value ? $value : array();

        array_push($value, $key);//进列

        if(count($value) > $this->_options['length']) {
            $key = array_shift($value);//出列
            $this->rm($key);// 删除缓存
        }

        return $fun[1]('think_queue', $value);
    }

    /**
     * 魔术方法__get
     *
     * @author          liu21st <liu21st@gmail.com>
     * @lastmodify      2013-01-16 13:27:30 by mashanling
     *
     * @param string $name 获取对象名称
     *
     * @return void 无返回值
     */
    public function __get($name) {
        $this->get($name);
    }

    /**
     * 魔术方法__set
     *
     * @author          liu21st <liu21st@gmail.com>
     * @lastmodify      2013-01-16 13:27:24 by mashanling
     *
     * @param string $name  设置对象名称
     * @param mixed  $value 设置值
     *
     * @return void 无返回值
     */
    public function __set($name, $value) {
        $this->set($name, $value);
    }

    /**
     * 魔术方法__unset
     *
     * @author          liu21st <liu21st@gmail.com>
     * @lastmodify      2013-01-16 13:28:49 by mashanling
     *
     * @param string $name 销毁对象名称
     *
     * @return void 无返回值
     */
    public function __unset($name) {
        $this->rm($name);
    }

    /**
     * 连接缓存
     *
     * @author          liu21st <liu21st@gmail.com>
     * @lastmodify      2013-01-16 13:29:06 by mashanling
     *
     * @param string $type    缓存类型
     * @param array  $options 缓存类配置数组
     *
     * @throws \RuntimeExecption 如果无法加载对应缓存类
     * @return object 缓存实例
     */
    public function connect($type = '', $options = array()) {
        $type  = $type ? $type : C('DATA_CACHE_TYPE');
        $type  = strtolower(trim($type));
        $class = 'Cache' . ucwords($type);

        if(is_file(CORE_PATH . ($v = 'Driver/Cache/' . $class . '.class.php'))) {//内置驱动
            $path = CORE_PATH;
        }
        else{//扩展驱动
            $path = EXTEND_PATH;
        }

        if(require_cache($path . $v)) {
            $cache = new $class($options);
        }
        else {
            throw new \RuntimeException(L('_CACHE_TYPE_INVALID_') . ':' . $type);
        }

        return $cache;
    }

    /**
     * 获取缓存配置值
     *
     * @author          liu21st <liu21st@gmail.com>
     * @lastmodify      2013-01-16 13:34:16 by mashanling
     *
     * @param string $name 配置名称
     *
     * @return mixed 配置值
     */
    public function getOptions($name) {
        return $this->_options[$name];
    }

    /**
     * 设置配置
     *
     * @author          liu21st <liu21st@gmail.com>
     * @lastmodify      2013-01-16 13:29:06 by mashanling
     *
     * @param string $name  配置名称
     * @param mixed  $value 配置值
     *
     * @return void 无返回值
     */
    public function setOptions($name, $value) {
        $this->_options[$name] = $value;
    }
}